package com.distribution.system.service.impl;

import cn.hutool.core.collection.ListUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.distribution.common.core.domain.entity.SysUser;
import com.distribution.common.exception.ServiceException;
import com.distribution.common.utils.DictUtils;
import com.distribution.framework.config.ServerConfig;
import com.distribution.system.domain.dto.AgentDTO;
import com.distribution.system.domain.dto.AgentProxyProductDTO;
import com.distribution.system.domain.dto.UpdateDaProxyProductDTO;
import com.distribution.system.domain.dto.UpdateSubAgentCommissionByDeductPercentDTO;
import com.distribution.system.domain.entity.CmccDaProduct;
import com.distribution.system.domain.entity.CmccDaProxyProductManage;
import com.distribution.system.domain.req.CmccDaProductListReq;
import com.distribution.system.domain.req.ProxyProductManageListReq;
import com.distribution.system.domain.vo.CmccDaProxyProductVO;
import com.distribution.system.domain.vo.ProductProxyVO;
import com.distribution.system.domain.vo.ProxyProductVO;
import com.distribution.system.mapper.CmccDaProxyProductManageMapper;
import com.distribution.system.mapper.SysUserMapper;
import com.distribution.system.service.CmccDaProductService;
import com.distribution.system.service.CmccDaProxyProductManageService;
import com.distribution.system.service.ISysUserService;
import com.distribution.system.utils.EncryptionUtil;
import lombok.extern.slf4j.Slf4j;
import org.apache.ibatis.exceptions.TooManyResultsException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.util.*;
import java.util.stream.Collectors;

import static com.distribution.common.utils.SecurityUtils.getUserId;
import static com.distribution.common.utils.SecurityUtils.getUsername;

/**
 * 代理卡信息表(CmccDaProxyProductManage)表服务实现类
 * @since 2023-05-21 16:08:28
 */
@Slf4j
@Service("cmccDaProxyProductManageService")
public class CmccDaProxyProductManageServiceImpl extends ServiceImpl<CmccDaProxyProductManageMapper, CmccDaProxyProductManage> implements CmccDaProxyProductManageService {
    private static final Logger agentProxyProductManageUpdateLog = LoggerFactory.getLogger("agentProxyProductManageUpdateLog");
    @Resource
    CmccDaProxyProductManageMapper cmccDaProxyProductManageMapper;
    @Resource
    SysUserMapper sysUserMapper;
    @Resource
    ISysUserService userService;
    @Resource
    private ServerConfig serverConfig;
    @Value("${swagger.pathMapping}")
    private String pathMapping;
    @Resource
    private CmccDaProductService cmccDaProductService;

    /**
     * @param updateDaProxyProductDTO 更新信息
     * @Author: GodLu
     * @Date: 2024/5/9 22:13
     * @Description: 更新代理卡配置
     * @return: void
     */
    @Transactional
    @Override
    public void updateAgentProxyProduct(UpdateDaProxyProductDTO updateDaProxyProductDTO) {
        SysUser sysUser = sysUserMapper.selectUserById(getUserId());
        if (sysUser.getRoleId() != 100 && sysUser.getRoleId() != 101 && !sysUser.isOperationSupervisor() && !sysUser.isAgentOperation() && sysUser.getRoleId() != 104) {
            throw new ServiceException("该角色不能修改代理信息");
        }
        SysUser sysUserUpdate = sysUserMapper.selectUserById(updateDaProxyProductDTO.getUserId());
        if (sysUserUpdate.isAgentOperation()) {
            throw new ServiceException("员工账号不能修改代理信息!");
        }
        if (!sysUser.isOperationSupervisor() && updateDaProxyProductDTO.getDownCommission().compareTo(updateDaProxyProductDTO.getMyCommission()) > 0) {
            throw new ServiceException("下级佣金不能大于我的佣金!");
        }
        /*if (!sysUser.isOperationSupervisor()) {
            CmccDaProduct cmccDaProduct = cmccDaProductService.getOne(new LambdaQueryWrapper<CmccDaProduct>()
                    .eq(CmccDaProduct::getProductCode, updateDaProxyProductDTO.getProductCode()));
            if (updateDaProxyProductDTO.getDownCommission().compareTo(cmccDaProduct.getBasicsCommission()) > 0) {
                throw new ServiceException("下级代理佣金不能大于商品的基础佣金!");
            }
        }*/
        CmccDaProxyProductManage proxyProductManage = getOne(new LambdaQueryWrapper<CmccDaProxyProductManage>()
                .eq(CmccDaProxyProductManage::getUserId,updateDaProxyProductDTO.getUserId())
                .eq(CmccDaProxyProductManage::getProductCode,updateDaProxyProductDTO.getProductCode()), false);
        if (proxyProductManage == null) {
            log.error("根据用户ID【{}】商品编码【{}】查找的商品配置信息为空或存在多条记录", updateDaProxyProductDTO.getUserId(),
                    updateDaProxyProductDTO.getProductCode());
            //throw new ServiceException("要修改的商品配置信息为空或存在多条记录");
            // 如果商品配置信息不存在则新增
            proxyProductManage = new CmccDaProxyProductManage();
            proxyProductManage.setUserId(updateDaProxyProductDTO.getUserId());
            proxyProductManage.setProductCode(updateDaProxyProductDTO.getProductCode());
            proxyProductManage.setProductState(updateDaProxyProductDTO.getProductState());
            String sysCardStatus = DictUtils.getDictLabel("sys_product_status", String.valueOf(updateDaProxyProductDTO.getProductState()));
            proxyProductManage.setProductStateDesc(sysCardStatus);
            proxyProductManage.setCollectFlag("0");
            proxyProductManage.setCreateTime(new Date());
            proxyProductManage.setCreateUserId(getUserId().intValue());
            proxyProductManage.setCreateUserName(getUsername());
            save(proxyProductManage);
        }
        proxyProductManage.setUpdateUserName(getUsername());
        proxyProductManage.setUpdateUserId(getUserId().intValue());
        proxyProductManage.setUpdateTime(new Date());
        if (updateDaProxyProductDTO.getProductState() != null && !Objects.equals(proxyProductManage.getProductState(), updateDaProxyProductDTO.getProductState())) {
            proxyProductManage.setProductState(updateDaProxyProductDTO.getProductState());
            String sysCardStatus = DictUtils.getDictLabel("sys_product_status", String.valueOf(updateDaProxyProductDTO.getProductState()));
            proxyProductManage.setProductStateDesc(sysCardStatus);
            updateAgentProxyProductStatus(updateDaProxyProductDTO.getUserId(), Collections.singletonList(updateDaProxyProductDTO.getProductCode()),0);
        }
        if (updateDaProxyProductDTO.getDownCommission() == null) {
            throw new ServiceException("下级佣金不能为空!");
        }
        proxyProductManage.setCommission(updateDaProxyProductDTO.getDownCommission());
        updateById(proxyProductManage);
    }

    /**
     * @param updateSubAgentCommissionByDeductPercentDTO 更新信息
     * @Author: GodLu
     * @Date: 2024/5/9 21:28
     * @Description: 更新下级佣金
     * @return: void
     */
    @Override
    @Transactional
    public void updateSubAgentCommissionByDeductPercent(UpdateSubAgentCommissionByDeductPercentDTO updateSubAgentCommissionByDeductPercentDTO) {
        SysUser currentSysUser = updateSubAgentCommissionByDeductPercentDTO.getCurrentSysUser();
        BigDecimal downCommission = updateSubAgentCommissionByDeductPercentDTO.getMyCommission();
        /** 校验各种条件 */
        if (currentSysUser == null) {
            throw new ServiceException("查不到当前用户!");
        }
        Long userId = currentSysUser.getUserId();
        // 如果当前角色不是总运营、代理运营、一二级代理，则无权限
        if (!currentSysUser.isOperationSupervisor() && !currentSysUser.isAgentOperation() && currentSysUser.getRoleId() != 100 && currentSysUser.getRoleId() != 101) {
            throw new ServiceException("该角色不能修改下级佣金");
        }
        // 如果要更新的卡不存在
        String productCode = updateSubAgentCommissionByDeductPercentDTO.getProductCode();
        CmccDaProduct cmccDaProduct = cmccDaProductService.getOne(new LambdaQueryWrapper<CmccDaProduct>()
                .eq(CmccDaProduct::getProductCode, productCode),false);
        if (cmccDaProduct == null){
            log.error("更新当前用户【{}】所有下级佣金时当前商品【{}】不存在或存在产品编号相同的商品", currentSysUser.getUserId(), productCode);
            throw new ServiceException("当前商品【" + productCode + "】不存在或存在产品编号相同的商品，请联系管理员");
        }
        // 如果当前用户是一二级代理
        if (currentSysUser.getRoleId() == 100 || currentSysUser.getRoleId() == 101){
            /*// 下级代理佣金不能高于商品本身的基础佣金
            if (downCommission.compareTo(cmccDaProduct.getBasicsCommission()) > 0) {
                log.error("商品编码为{}的产品下级代理佣金{}不能大于商品的基础佣金{}", cmccDaProduct.getProductCode(), downCommission, cmccDaProduct.getBasicsCommission());
                throw new ServiceException("下级代理佣金不能大于商品的基础佣金!");
            }*/
            // 一二级代理设置的下级佣金不能大于自己的佣金
            // 查看当前 用户 当前卡的卡信息
            try {
                System.out.println(userId + " | " + productCode);
                CmccDaProxyProductManage cmccDaProxyProductManage = getOne(new LambdaQueryWrapper<CmccDaProxyProductManage>()
                        .eq(CmccDaProxyProductManage::getUserId, userId)
                        .eq(CmccDaProxyProductManage::getProductCode, productCode));
                if (downCommission.compareTo(cmccDaProxyProductManage.getCommission()) > 0) {
                    throw new ServiceException("下级佣金不能大于自己佣金");
                }
            } catch (TooManyResultsException tooManyResultsException) {
                throw new ServiceException("当前卡配置不存在或存在产品编号相同的卡配置，请联系管理员");
            }
        }
        /** 查找所有下级用户和产品配置信息并匹配起来 */
        // 查找当前用户的所有下级
        AgentDTO agentDTO = new AgentDTO();
        agentDTO.setParentId(userId);
//        List<SysUser> allSubAgentSysUser = sysUserMapper.selectAllUserListByParentId(agentDTO);
        List<SysUser> allSubAgentSysUser = userService.selectUserListByParentId(agentDTO);
        //System.out.println("修改产品配置信息时 = " + allSubAgentSysUser.stream().collect(Collectors.toMap(SysUser::getUserId,SysUser::getSupDeductPercent)));
//        if (allSubAgentSysUser.isEmpty()) throw new ServiceException("查不到下级代理！");
        if (allSubAgentSysUser.isEmpty()) {
            log.error("当前用户【{}】没有下级代理，无需继续执行", userId);
        }
        List<Long> allSubAgentIdList = allSubAgentSysUser.stream().map(SysUser::getUserId).collect(Collectors.toList());
        // 当前商品编码的所有产品配置信息
        List<CmccDaProxyProductManage> allProxyProductManageList = list(new LambdaQueryWrapper<CmccDaProxyProductManage>()
                .eq(CmccDaProxyProductManage::getProductCode, productCode)
                .in(CmccDaProxyProductManage::getUserId, allSubAgentIdList));
        // 匹配用户信息与产品配置信息
        Map<SysUser,CmccDaProxyProductManage> allSubUserProductManageMap = getSysUserProxyProductManageMap(cmccDaProduct, allSubAgentSysUser, allProxyProductManageList);

        /** 查询各级代理信息集合，ID集合，有下级的上级代理集合，用户信息与产品配置信息匹配的Map等信息 */
        // 下一级用户
        List<SysUser> firstSubAgentSysUsers = new ArrayList<>();
        // 下一级ID集合
        List<Long> firstSubAgentIdsList;
        Map<SysUser, CmccDaProxyProductManage> firstSubUserProductManageMap = new HashMap<>();
        // 下二级用户
        List<SysUser> secondSubAgentSysUsers = new ArrayList<>();
        // 下二级ID集合
        List<Long> secondSubAgentIdsList;
        // 一级中有下级的用户ID集合
        List<Long> firstHasSubAgentIdList = new ArrayList<>();
        Map<SysUser, CmccDaProxyProductManage> secondSubUserProductManageMap = new HashMap<>();
        // 下三级用户
        List<SysUser> thirdSubAgentSysUsers = new ArrayList<>();
        // 下三级ID集合
        List<Long> thirdSubAgentIdsList;
        // 二级中有下级的用户ID集合
        List<Long> secondHasSubAgentIdList = new ArrayList<>();
        Map<SysUser, CmccDaProxyProductManage> thirdSubUserProductManageMap = new HashMap<>();
        if (currentSysUser.isOperationSupervisor()) {// 运营代理则查询所有一级代理
            List<Long> roleId = new ArrayList<>();
            roleId.add(100L);
            firstSubAgentSysUsers = sysUserMapper.selectUserListByRoleId(roleId);
        } else {// 否则查询自己下一级
            AgentDTO agentDTO1 = new AgentDTO();
            agentDTO1.setParentId(userId);
//            firstSubAgentSysUsers = sysUserMapper.selectUserListByParentId(agentDTO1);
            firstSubAgentSysUsers = userService.selectUserListByParentId(agentDTO1);
        }
        // 下一级ID集合
        firstSubAgentIdsList = firstSubAgentSysUsers.stream().map(SysUser::getUserId).collect(Collectors.toList());
        firstSubUserProductManageMap = allSubUserProductManageMap.entrySet().stream()
                .filter(f -> firstSubAgentIdsList.contains(f.getKey().getUserId())).collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue));
        if (firstSubUserProductManageMap.isEmpty()) return;
        // 不是二级代理则有下二级
        if (currentSysUser.getRoleId() != 101){
            secondSubAgentSysUsers = allSubAgentSysUser.stream().filter(f -> firstSubAgentIdsList.contains(f.getParentId())).collect(Collectors.toList());
            secondSubAgentIdsList = secondSubAgentSysUsers.stream().map(SysUser::getUserId).collect(Collectors.toList());
            firstHasSubAgentIdList = secondSubAgentSysUsers.stream().map(SysUser::getParentId).collect(Collectors.toList());
            secondSubUserProductManageMap = allSubUserProductManageMap.entrySet().stream()
                    .filter(f -> secondSubAgentIdsList.contains(f.getKey().getUserId())).collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue));
            // 不是一级代理则有下三级
            if (currentSysUser.getRoleId() != 100){
                thirdSubAgentSysUsers = allSubAgentSysUser.stream().filter(f -> secondSubAgentIdsList.contains(f.getParentId())).collect(Collectors.toList());
                thirdSubAgentIdsList = thirdSubAgentSysUsers.stream().map(SysUser::getUserId).collect(Collectors.toList());
                secondHasSubAgentIdList = thirdSubAgentSysUsers.stream().map(SysUser::getParentId).collect(Collectors.toList());
                thirdSubUserProductManageMap = allSubUserProductManageMap.entrySet().stream()
                        .filter(f -> thirdSubAgentIdsList.contains(f.getKey().getUserId())).collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue));
            }else {
                thirdSubAgentIdsList = new ArrayList<>();
            }
        } else {
            secondSubAgentIdsList = new ArrayList<>();
            thirdSubAgentIdsList = new ArrayList<>();
        }
        /** 分情况更新下级的产品配置信息（总运营和代理运营修改数据较多所以使用多线程，一二级代理修改数据相对较少所以不适用多线程） */
        // 要保存的代理产品配置
        List<CmccDaProxyProductManage> updateAgentProxyProductManageList = new ArrayList<>();
        // 更新一级
        for (Map.Entry<SysUser, CmccDaProxyProductManage> entry1 : firstSubUserProductManageMap.entrySet()) {
            SysUser sysUser = entry1.getKey();
//            System.out.println("sysUser = " + sysUser.getUserId());
            CmccDaProxyProductManage proxyProductManage1 = entry1.getValue();
            CmccDaProxyProductManage deductProxyProductManage1 = getDeductProxyProductManage(proxyProductManage1, downCommission, sysUser);
            if (deductProxyProductManage1 == null) continue;
//            System.out.println("deductProxyProductManage1 = " + deductProxyProductManage1.getUserId());
            updateAgentProxyProductManageList.add(deductProxyProductManage1);
            if (firstHasSubAgentIdList.contains(sysUser.getUserId())) {
                Map<SysUser, CmccDaProxyProductManage> collect2 = secondSubUserProductManageMap.entrySet().stream()
                        .filter(f -> deductProxyProductManage1.getUserId().equals(f.getKey().getParentId()))
                        .collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue));
                // 更新二级
                for (Map.Entry<SysUser, CmccDaProxyProductManage> entry2 : collect2.entrySet()) {
                    SysUser sysUser2 = entry2.getKey();
                    CmccDaProxyProductManage deductProxyProductManage2 = getDeductProxyProductManage(entry2.getValue(),
                            deductProxyProductManage1.getCommission(), sysUser2);
                    if (deductProxyProductManage2 == null) continue;
//                    System.out.println("deductProxyProductManage2 = " + deductProxyProductManage2);
                    updateAgentProxyProductManageList.add(deductProxyProductManage2);
                    if (secondHasSubAgentIdList.contains(sysUser2.getUserId())){
                        Map<SysUser, CmccDaProxyProductManage> collect3 = thirdSubUserProductManageMap.entrySet().stream()
                                .filter(f -> deductProxyProductManage2.getUserId().equals(f.getKey().getParentId()))
                                .collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue));
                        // 更新三级
                        for (Map.Entry<SysUser, CmccDaProxyProductManage> entry3 : collect3.entrySet()) {
                            SysUser sysUser3 = entry3.getKey();
                            CmccDaProxyProductManage deductProxyProductManage3 = getDeductProxyProductManage(entry3.getValue(),
                                    deductProxyProductManage2.getCommission(), sysUser3);
                            if (deductProxyProductManage3 == null) continue;
//                            System.out.println("deductProxyProductManage3 = " + deductProxyProductManage3);
                            updateAgentProxyProductManageList.add(deductProxyProductManage3);
                        }
                    }
                }
            }
        }
        /*System.out.println("updateAgentProxyProductManageList.stream().map(CmccDaProxyProductManage::getUserId).collect(Collectors.toList()) = "
                + updateAgentProxyProductManageList.stream().map(CmccDaProxyProductManage::getUserId).collect(Collectors.toList()));*/
        if (!updateAgentProxyProductManageList.isEmpty()) {
            //updateBatchById(updateFirstAgentProxyProductManageList);
            updateProxyProductManageList(updateAgentProxyProductManageList);
        }
    }
    // 获取抽成后的商品配置
    private CmccDaProxyProductManage getDeductProxyProductManage(CmccDaProxyProductManage subProxyProductManage, BigDecimal supCommission, SysUser sysUser){
//        System.out.println(subProxyProductManage.getProductCode() + "上级佣金 = " + supCommission);
//        System.out.println("subProxyProductManage = " + subProxyProductManage.getUserId() + "丨" + subProxyProductManage.getProductCode());
        BigDecimal currentCommission = getCommissionByDeduct(supCommission, sysUser.getSupDeduct());
        // 佣金没有变化则返回空
        if (subProxyProductManage.getCommission().compareTo(currentCommission) == 0) return null;
//        System.out.println(subProxyProductManage.getProductCode() + "下级佣金 = " + currentCommission);
        subProxyProductManage.setCommission(currentCommission);
        subProxyProductManage.setUpdateTime(new Date());
        subProxyProductManage.setUpdateUserId(sysUser.getUserId().intValue());
        subProxyProductManage.setUpdateUserName(getUsername());
        return subProxyProductManage;
    }

    // 根据上级抽成和上级佣金计算自己的佣金
    @Override
    public BigDecimal getCommissionByDeduct(BigDecimal supCommission, Double superDeduct) {
        // 设置佣金
        BigDecimal currentCommission = supCommission;
        if (superDeduct != null && superDeduct > 0){
            if (superDeduct < 1){// 小于1则为百分比
                BigDecimal superDeductValue = supCommission.multiply(BigDecimal.valueOf(superDeduct)).setScale(0, RoundingMode.HALF_UP);
                // 上级抽成不能小于零
                superDeductValue = superDeductValue.compareTo(BigDecimal.ZERO) < 0 ? BigDecimal.ZERO : superDeductValue;
                currentCommission = supCommission.subtract(superDeductValue);
            }else if (BigDecimal.valueOf(superDeduct).compareTo(supCommission) < 0){// 大于等于1且小于上级佣金则为抽指定金额
                currentCommission = supCommission.subtract(BigDecimal.valueOf(superDeduct));
            }
        }
        return currentCommission;
    }

    /**
    * @Author: GodLu
    * @Date: 2024/7/24 8:56
    * @Description: 获取用户信息和产品配置信息映射关系
    * @param allSubAgentSysUser 所有下级代理用户信息
    * @param allProxyProductManageList 所有下级产品配置信息
    * @return: Map<SysUser,CmccDaProxyProductManage>
    */
    @Transactional
    public Map<SysUser,CmccDaProxyProductManage> getSysUserProxyProductManageMap(CmccDaProduct cmccDaProduct, List<SysUser> allSubAgentSysUser, List<CmccDaProxyProductManage> allProxyProductManageList){
        Map<SysUser,CmccDaProxyProductManage> allSysUserProxyProductManageMap = new HashMap<>();
//        System.out.println(allSubAgentSysUser.stream().map(SysUser::getUserId).collect(Collectors.toList()));
        for (SysUser sysUser : allSubAgentSysUser) {
//            System.out.println(allProxyProductManageList.stream().map(CmccDaProxyProductManage::getUserId).collect(Collectors.toList()));
            List<CmccDaProxyProductManage> proxyProductManageList = allProxyProductManageList.stream()
                    .filter(f -> sysUser.getUserId().equals(f.getUserId())).collect(Collectors.toList());
            if (!proxyProductManageList.isEmpty()) {
                allSysUserProxyProductManageMap.put(sysUser, proxyProductManageList.get(0));
            }else {
                // 若用户没有此商品配置则新增
                CmccDaProxyProductManage cmccDaProxyProductManage = new CmccDaProxyProductManage();
                cmccDaProxyProductManage.setProductCode(cmccDaProduct.getProductCode());
                cmccDaProxyProductManage.setUserId(sysUser.getUserId());
                cmccDaProxyProductManage.setCommission(BigDecimal.ZERO);
                cmccDaProxyProductManage.setCollectFlag("0");
                cmccDaProxyProductManage.setProductState(1);
                cmccDaProxyProductManage.setProductStateDesc("上线");
                cmccDaProxyProductManage.setPromotionFlag("1");
                cmccDaProxyProductManage.setCreateTime(new Date());
                cmccDaProxyProductManage.setCreateUserId(sysUser.getUserId().intValue());
                cmccDaProxyProductManage.setCreateUserName(getUsername());
                cmccDaProxyProductManage.setUpdateTime(new Date());
                cmccDaProxyProductManage.setUpdateUserId(sysUser.getUserId().intValue());
                cmccDaProxyProductManage.setUpdateUserName(getUsername());
                allSysUserProxyProductManageMap.put(sysUser, cmccDaProxyProductManage);
            }
        }
        return allSysUserProxyProductManageMap;
    }

    public void updateProxyProductManageList(List<CmccDaProxyProductManage> cmccDaProxyProductManageList){
//        System.out.println("开始更新" + cmccDaProxyProductManageList.stream().map(CmccDaProxyProductManage::getUserId).collect(Collectors.toList()));
        // id为空的批量保存
        List<CmccDaProxyProductManage> saveProxyProductManageList = cmccDaProxyProductManageList.stream()
                .filter(f -> Objects.isNull(f.getId())).collect(Collectors.toList());
        if (!saveProxyProductManageList.isEmpty()){
            ListUtil.partition(saveProxyProductManageList, 500).forEach(this::saveBatch);
        }
        // id不为空的批量更新
        List<CmccDaProxyProductManage> updateProxyProductManageList = cmccDaProxyProductManageList.stream()
                .filter(f -> Objects.nonNull(f.getId())).collect(Collectors.toList());
        if (!updateProxyProductManageList.isEmpty()){
            ListUtil.partition(updateProxyProductManageList, 500).forEach(this::updateBatchById);
        }
        //System.out.println("更新完成");
        cmccDaProxyProductManageList.forEach(m -> {
            log.info("修改的用户ID为【{}】的产品编码为【{}】的产品佣金为【{}】", m.getUserId(), m.getProductCode(), m.getCommission());
            agentProxyProductManageUpdateLog.info("修改的用户ID为【{}】的产品编码为【{}】的产品佣金为【{}】", m.getUserId(), m.getProductCode(), m.getCommission());
        });
    }

    /**
     * @param cmccDaProduct 要统一佣金的商品
     * @Author: GodLu
     * @Date: 2024/5/9 23:11
     * @Description: 统一所有代理当前商品佣金
     * @return: void
     */
    @Override
    public void unifiedCommission(CmccDaProduct cmccDaProduct) {
        CmccDaProduct one = cmccDaProductService.getOne(new LambdaQueryWrapper<CmccDaProduct>().eq(CmccDaProduct::getProductCode,cmccDaProduct.getProductCode()), false);
        if (one == null) {
            throw new ServiceException("查无此商品!");
        }
        lambdaUpdate().set(CmccDaProxyProductManage::getCommission, one.getBasicsCommission())
                .set(CmccDaProxyProductManage::getUpdateTime, new Date())
                .set(CmccDaProxyProductManage::getUpdateUserId, getUserId())
                .set(CmccDaProxyProductManage::getUpdateUserName, getUsername())
                .eq(CmccDaProxyProductManage::getProductCode, cmccDaProduct.getProductCode()).update();
    }

    @Override
    public ProxyProductVO selectAgentProxyProductVO(AgentProxyProductDTO agentProxyProductDTO) {
        agentProxyProductDTO.setLoginUserId(getUserId());
        ProxyProductVO proxyCardVO = new ProxyProductVO();
        SysUser loginSysUser = sysUserMapper.selectUserById(getUserId());
        if (loginSysUser.getDeptId() == 101) agentProxyProductDTO.setPromoteChannel("0");
        if (loginSysUser.getDeptId() == 102) agentProxyProductDTO.setPromoteChannel("1");
        List<CmccDaProxyProductVO> daProxyProductVOList = new ArrayList<>();
        if (loginSysUser.isAdmin() || loginSysUser.isOperationSupervisor() || loginSysUser.isAgentOperation()) {
            daProxyProductVOList = cmccDaProxyProductManageMapper.selectAgentProxyProductYunYing(agentProxyProductDTO);
        } else {
            daProxyProductVOList = cmccDaProxyProductManageMapper.selectAgentProxyProduct(agentProxyProductDTO);
        }

        String url = serverConfig.getUrl();
        daProxyProductVOList.forEach(a -> {
            a.setMainImagePath(url + pathMapping + a.getMainImagePath());
            a.setUnOrderProductUrl(url + "/promotion?userId=" + EncryptionUtil.encodeBase64(String.valueOf(agentProxyProductDTO.getUserId())) + "&productCode=" + a.getProductCode());
        });
        SysUser sysUser = sysUserMapper.selectUserById(agentProxyProductDTO.getUserId());
        proxyCardVO.setSysUser(sysUser);
        proxyCardVO.setCmccDaProxyProductVOS(daProxyProductVOList);
        return proxyCardVO;
    }

    @Override
    public List<ProductProxyVO> selectProxyProductList(ProxyProductManageListReq proxyProductManageListReq) {
        return cmccDaProxyProductManageMapper.selectProxyProductList(proxyProductManageListReq);
    }

    /**
     * @Author: GodLu
     * @Date: 2024/5/13 17:47
     * @Description: 更新所有代理指定商品编号的商品配置状态
     * @param productCode 商品编码
     * @return: void
     */
    @Transactional
    @Override
    public void updateAllAgentProxyProductStatus(String productCode, Integer productState) {
        // 查询已存在的商品配置信息
        List<CmccDaProxyProductManage> proxyProductManageList = lambdaQuery().eq(CmccDaProxyProductManage::getProductCode, productCode).list();
        List<Long> proxyProductManageIdList = proxyProductManageList.stream().map(CmccDaProxyProductManage::getUserId).collect(Collectors.toList());
        // 查询所有一二三级代理
        List<Long> roles = Arrays.asList(100L, 101L, 102L);
        List<SysUser> sysUserList = sysUserMapper.selectUserListByRoleId(roles);
        List<Long> userIdList = sysUserList.stream().map(SysUser::getUserId).collect(Collectors.toList());
        // 匹配没有此商品配置的代理
        userIdList.removeAll(proxyProductManageIdList);
        if (userIdList.isEmpty()){
            lambdaUpdate()
                    .eq(CmccDaProxyProductManage::getProductCode, productCode)
                    .set(CmccDaProxyProductManage::getProductState, productState)
                    .set(CmccDaProxyProductManage::getProductStateDesc, DictUtils.getDictLabel("sys_product_status", String.valueOf(productState)))
                    .update();
        }else {
            CmccDaProduct one = cmccDaProductService.lambdaQuery().eq(CmccDaProduct::getProductCode, productCode).one();
            List<CmccDaProxyProductManage> saveProxyProductManageList = new ArrayList<>();
            userIdList.forEach(f -> {
                // 若用户没有此商品配置则新增
                CmccDaProxyProductManage cmccDaProxyProductManage = new CmccDaProxyProductManage();
                cmccDaProxyProductManage.setProductCode(productCode);
                cmccDaProxyProductManage.setUserId(f);
                cmccDaProxyProductManage.setCommission(one.getBasicsCommission());
                cmccDaProxyProductManage.setCollectFlag("0");
                cmccDaProxyProductManage.setProductState(productState);
                cmccDaProxyProductManage.setProductStateDesc(DictUtils.getDictLabel("sys_product_status", String.valueOf(productState)));
                cmccDaProxyProductManage.setPromotionFlag("1");
                cmccDaProxyProductManage.setCreateTime(new Date());
                cmccDaProxyProductManage.setCreateUserId(f.intValue());
                cmccDaProxyProductManage.setCreateUserName(getUsername());
                cmccDaProxyProductManage.setUpdateTime(new Date());
                cmccDaProxyProductManage.setUpdateUserId(f.intValue());
                cmccDaProxyProductManage.setUpdateUserName(getUsername());
                saveProxyProductManageList.add(cmccDaProxyProductManage);
            });
            if (!saveProxyProductManageList.isEmpty()){
                saveBatch(saveProxyProductManageList);
            }
        }
    }

    @Transactional
    @Override
    public void updateAgentProxyProductStatus(Long userId, List<String> productCodeList, Integer productState) {
        AgentDTO agentDTO = new AgentDTO();
        agentDTO.setParentId(userId);
//        List<SysUser> allSubUserList = sysUserMapper.selectUserListByParentId(agentDTO);
        List<SysUser> allSubUserList = userService.selectUserListByParentId(agentDTO);
        List<Long> allSubUserIdList = allSubUserList.stream().map(SysUser::getUserId).collect(Collectors.toList());
        allSubUserIdList.add(userId);
        lambdaUpdate()
                .in(CmccDaProxyProductManage::getUserId,allSubUserIdList)
                .in(CmccDaProxyProductManage::getProductCode, productCodeList)
                .set(CmccDaProxyProductManage::getProductState, productState)
                .set(CmccDaProxyProductManage::getProductStateDesc, DictUtils.getDictLabel("sys_product_status", String.valueOf(productState)))
                .update();
    }

    // 给下级代理添加所有商品管理
    @Transactional
    @Override
    public void addAllProxyProductManageToSubAgent(SysUser supSysUserAgent, SysUser subSysUserAgent) {
        Long userId = supSysUserAgent.getUserId();
        String username = supSysUserAgent.getUserName();
        Date date = new Date();
        if (!supSysUserAgent.isOperationSupervisor()) {//总运营相当于开员工账号 无需卡配置
            // 要添加的产品配置信息
            List<CmccDaProxyProductManage> addProxyProductManageList = new ArrayList<>();
            if (supSysUserAgent.isAgentOperation()) {// 代理运营开一级代理账号，需添根据产品信息添加商品配置信息
                String promoteChannel = "0";
                if (subSysUserAgent.getDeptId() == 102L) promoteChannel = "1";
                List<CmccDaProduct> list = cmccDaProductService.lambdaQuery()
                        .eq(CmccDaProduct::getProductStatus, "1")
                        .eq(CmccDaProduct::getPromoteChannel, promoteChannel)
                        .list();
                list.forEach(b->{
                    CmccDaProxyProductManage cmccDaProxyProductManage = new CmccDaProxyProductManage();
                    cmccDaProxyProductManage.setUserId(subSysUserAgent.getUserId());
                    cmccDaProxyProductManage.setProductCode(b.getProductCode());
                    cmccDaProxyProductManage.setProductState(Integer.valueOf(b.getProductStatus()));
                    String sysCardStatus = DictUtils.getDictLabel("sys_product_status", String.valueOf(b.getProductStatus()));
                    cmccDaProxyProductManage.setProductStateDesc(sysCardStatus);
                    cmccDaProxyProductManage.setProductCode(b.getProductCode());
                    // 设置佣金(代理运营的下级就是一级代理，没有抽成，直接设置佣金即可)
                    cmccDaProxyProductManage.setCommission(b.getBasicsCommission() != null ? b.getBasicsCommission() : new BigDecimal(0));
                    cmccDaProxyProductManage.setCreateTime(date);
                    cmccDaProxyProductManage.setUpdateTime(date);
                    cmccDaProxyProductManage.setCreateUserId(userId.intValue());
                    cmccDaProxyProductManage.setCreateUserName(username);
                    addProxyProductManageList.add(cmccDaProxyProductManage);
                });
            }else {// 其他的就是一二级代理了
                //查询当前代理所有商品配置信息
                List<CmccDaProxyProductManage> cmccDaProxyProductManageList = lambdaQuery().eq(CmccDaProxyProductManage::getUserId, userId).list();
                // 遍历并添加商品配置信息
                cmccDaProxyProductManageList.forEach(f -> {
                    CmccDaProxyProductManage cmccDaProxyProductManage = new CmccDaProxyProductManage();
                    cmccDaProxyProductManage.setUserId(subSysUserAgent.getUserId());
                    cmccDaProxyProductManage.setProductCode(f.getProductCode());
                    cmccDaProxyProductManage.setProductState(f.getProductState());
                    String sysCardStatus = DictUtils.getDictLabel("sys_product_status", String.valueOf(f.getProductState()));
                    cmccDaProxyProductManage.setProductStateDesc(sysCardStatus);
                    cmccDaProxyProductManage.setProductCode(f.getProductCode());
                    // 设置佣金
                    cmccDaProxyProductManage.setCommission(getCommissionByDeduct(f.getCommission(), subSysUserAgent.getSupDeduct()));
                    cmccDaProxyProductManage.setCreateTime(date);
                    cmccDaProxyProductManage.setUpdateTime(date);
                    cmccDaProxyProductManage.setCreateUserId(userId.intValue());
                    cmccDaProxyProductManage.setCreateUserName(username);
                    addProxyProductManageList.add(cmccDaProxyProductManage);
                });
            }
            if (!addProxyProductManageList.isEmpty()) {
                saveBatch(addProxyProductManageList);
            }
        }
    }

    @Transactional
    @Override
    public void addProxyProductManageToAllAgent(CmccDaProduct cmccDaProduct) {
        // 如果存在当前商品编码的商品配置信息则删除
        List<CmccDaProxyProductManage> list = list(new LambdaUpdateWrapper<CmccDaProxyProductManage>()
                .eq(CmccDaProxyProductManage::getProductCode, cmccDaProduct.getProductCode()));
        if (!list.isEmpty()){
            List<Integer> idList = list.stream().map(CmccDaProxyProductManage::getId).collect(Collectors.toList());
            removeByIds(idList);
        }
        // 保证要添加的商品配置信息不存在
        int count = count(new LambdaQueryWrapper<CmccDaProxyProductManage>()
                .eq(CmccDaProxyProductManage::getProductCode, cmccDaProduct.getProductCode()));
        if (count > 0){
            throw new ServiceException("添加商品配置信息失败，当前商品编码的商品配置信息已存在！");
        }
        // 所有一二三级代理用户信息
        List<Long> roleIds = new ArrayList<>();
        roleIds.add(100L);
        roleIds.add(101L);
        roleIds.add(102L);
        List<SysUser> allAgentSysUserList = sysUserMapper.selectUserListByRoleId(roleIds);
        // 一级代理用户信息
        List<SysUser> subFirstAgentSysUserList = allAgentSysUserList.stream().filter(f -> f.getRoleId() == 100).collect(Collectors.toList());
        // 二级代理用户信息
        List<SysUser> subSecondAgentSysUserList = allAgentSysUserList.stream().filter(f -> f.getRoleId() == 101).collect(Collectors.toList());
        // 三级代理用户信息
        List<SysUser> subThirdAgentSysUserList = allAgentSysUserList.stream().filter(f -> f.getRoleId() == 102).collect(Collectors.toList());
        // 一级代理中有下级代理的用户信息
        List<Long> subSecondAgentParentIdList = subSecondAgentSysUserList.stream().map(SysUser::getParentId).collect(Collectors.toList());
        List<SysUser> subFirstHasSubAgentSysUser = subFirstAgentSysUserList.stream().filter(f -> subSecondAgentParentIdList.contains(f.getUserId())).collect(Collectors.toList());
        // 二级代理中有下级代理的用户信息
        List<Long> subThirdAgentParentIdList = subSecondAgentSysUserList.stream().map(SysUser::getParentId).collect(Collectors.toList());
        List<SysUser> subSecondHasSubAgentSysUser = subFirstAgentSysUserList.stream().filter(f -> subThirdAgentParentIdList.contains(f.getUserId())).collect(Collectors.toList());
        // 要保存的产品配置信息
        List<CmccDaProxyProductManage> saveProxyProductManageList = new ArrayList<>();
        subFirstAgentSysUserList.forEach(subFirstAgentSysUser -> {
            // 一级代理佣金为商品基础佣金
            BigDecimal firstAgentProductCommission = cmccDaProduct.getBasicsCommission();
            saveProxyProductManageList.add(genProxyProductManage(subFirstAgentSysUser, cmccDaProduct, firstAgentProductCommission));
            if (subFirstHasSubAgentSysUser.contains(subFirstAgentSysUser)){
                //System.out.println("有下级的一级代理 = " + subFirstAgentSysUser.getUserId());
                subSecondAgentSysUserList.forEach(subSecondAgentSysUser -> {
                    if (Objects.equals(subSecondAgentSysUser.getParentId(), subFirstAgentSysUser.getUserId())){
                        // 二级代理佣金计算
                        BigDecimal secondAgentProductCommission = getCommissionByDeduct(firstAgentProductCommission, subSecondAgentSysUser.getSupDeduct());
                        saveProxyProductManageList.add(genProxyProductManage(subSecondAgentSysUser, cmccDaProduct, secondAgentProductCommission));
                        if (subSecondHasSubAgentSysUser.contains(subSecondAgentSysUser)){
                            //System.out.println("有下级的二级代理 = " + subSecondAgentSysUser.getUserId());
                            subThirdAgentSysUserList.forEach(subThirdAgentSysUser -> {
                                if (Objects.equals(subThirdAgentSysUser.getParentId(), subSecondAgentSysUser.getUserId())){
                                    // 三级代理佣金计算
                                    BigDecimal thirdAgentProductCommission = getCommissionByDeduct(secondAgentProductCommission, subThirdAgentSysUser.getSupDeduct());
                                    saveProxyProductManageList.add(genProxyProductManage(subThirdAgentSysUser, cmccDaProduct, thirdAgentProductCommission));
                                }
                            });
                        }
                    }
                });
            }
        });
        if (!saveProxyProductManageList.isEmpty()) {
            //System.out.println("添加产品配置信息集合 = " + saveProxyProductManageList.size());
            cmccDaProxyProductManageMapper.insertBatchInfo(saveProxyProductManageList);
            /*List<List<CmccDaProxyProductManage>> partition = ListUtil.partition(saveProxyProductManageList, 500);
            partition.forEach(p -> {
                cmccDaProxyProductManageMapper.insertBatchInfo(p);
            });*/
        }
    }
    private CmccDaProxyProductManage genProxyProductManage(SysUser sysUser, CmccDaProduct cmccDaProduct, BigDecimal commission){
        int currentSysUserId = getUserId().intValue();
        String currentSysUserName = getUsername();
        Date date = new Date();
        CmccDaProxyProductManage cmccDaProxyProductManage = new CmccDaProxyProductManage();
        cmccDaProxyProductManage.setUserId(sysUser.getUserId());
        cmccDaProxyProductManage.setProductCode(cmccDaProduct.getProductCode());
        cmccDaProxyProductManage.setCommission(commission);
        // 若所属部门为推广中心，则默认隐藏商品配置信息
        if (sysUser.getDeptId() == 102L){
            cmccDaProxyProductManage.setProductState(0);
            String productStatus = DictUtils.getDictLabel("sys_product_status", "0");
            cmccDaProxyProductManage.setProductStateDesc(productStatus);
        }else {
            cmccDaProxyProductManage.setProductState(Integer.valueOf(cmccDaProduct.getProductStatus()));
            String productStatus = DictUtils.getDictLabel("sys_product_status", cmccDaProduct.getProductStatus());
            cmccDaProxyProductManage.setProductStateDesc(productStatus);
        }
        cmccDaProxyProductManage.setCreateUserId(currentSysUserId);
        cmccDaProxyProductManage.setCreateUserName(currentSysUserName);
        cmccDaProxyProductManage.setUpdateUserId(currentSysUserId);
        cmccDaProxyProductManage.setUpdateUserName(currentSysUserName);
        cmccDaProxyProductManage.setCreateTime(date);
        cmccDaProxyProductManage.setUpdateTime(date);
        return cmccDaProxyProductManage;
    }
}
